/*
 *  Description: BOAT XU SOFT FHSS
 *  Version: V1.00
 *  Author: boat xu
 *  Email: xifengzui@outlook.com
 *  Date: 2020-07-03 10:37:42
 *  LastEditTime: 2020-07-18 14:33:38
 */ 

#include "bsf_types.h"
#include "bsf_rand.h"
#include "random.h"
#include "bsf_debug.h"
b_u8_t weight_table[BSF_RAND_FREQCUTNUM] = {0};
b_u8_t shadow_table[BSF_RAND_FREQCUTNUM] = {0};




//用户初始化各个频段的权重
void bsf_rand_init(void) 
{
    b_u8_t ii= 0;
    dprintf("        CALL:bsf_rand_init");
    set_random_seed(BSF_RAND_DEFAULT_SEED);
    for(ii=0;ii<BSF_RAND_FREQCUTNUM;ii++)
    {
        weight_table[ii] = BSF_RAND_WEIGHT;
        shadow_table[ii] = BSF_RAND_WEIGHT;
    }
}

b_u8_t *bsf_rand_getTable(void)
{
    return weight_table;
}

void bsf_rand_set_default(void)
{
    bsf_rand_init();
}

void bsf_rand_set(b_u16_t seed,b_u8_t *tab)
{
    b_u8_t ii= 0;
    set_random_seed(seed);
    if(tab != b_null)
    {
        for(ii=0;ii<BSF_RAND_FREQCUTNUM;ii++)
        {
            weight_table[ii] = tab[ii];
            shadow_table[ii] = tab[ii];
        }
    }
    
}

//根据设置生成一个随机数
b_u8_t bsf_rand_Next(void)
{
    b_u8_t ii = 0;
    b_u8_t ret = 0;
    b_u8_t weCal = 0;
    ret = get_random_u8()%(BSF_RAND_WEIGHT*BSF_RAND_FREQCUTNUM)+1;
    for(ii=0;ii<BSF_RAND_FREQCUTNUM;ii++)
    {
        get_random_u8();//当权重变化后随机扰动
        weCal+=weight_table[ii];
        if(weCal>ret)
        {
            return ((128/BSF_RAND_FREQCUTNUM)*ii)+ get_random_u8()%(128/BSF_RAND_FREQCUTNUM);
        }
    }
    return get_random_u8()%128;//当权重表的和小于WEIGHT*FREQCUTNUM 的时候，随机返回0~128内的值
}

void bsf_rand_update(void)
{
    b_u8_t ii= 0;
    for(ii=0;ii<BSF_RAND_FREQCUTNUM;ii++)
    {
        weight_table[ii] = shadow_table[ii];
    }
}


//这里不可以调用_1的随意函数，否则会影响原序列
//丢掉特定组的权重,可以在传包失败的时候丢到特定通道的权重 选中通道的概率会变低
void bsf_rand_loss(b_u8_t freq)
{
    b_u8_t band = freq/(128/BSF_RAND_FREQCUTNUM);
    b_u8_t ofst = 0;
    ofst = get_random_u8()%(BSF_RAND_FREQCUTNUM-1);//0~6
    if(shadow_table[band] > 0)
    {
        shadow_table[(band+ofst+1)%BSF_RAND_FREQCUTNUM] +=1;//1~7的通道偏移
        shadow_table[band] -=1;
    }
}

//随机恢复某个通道的权重
void bsf_rand_recover(void)//对应的通道
{
    b_u8_t ii = 0;
    b_u8_t chn = get_random_u8();
    if(chn%2)
    {
        for(ii=0;ii<BSF_RAND_FREQCUTNUM;ii++)
        {
            if(shadow_table[(ii+chn)%BSF_RAND_FREQCUTNUM] <BSF_RAND_WEIGHT)
            {
                shadow_table[(ii+chn)%BSF_RAND_FREQCUTNUM]++;
                break;
            }
        }
    }
    else
    {
        for(ii=BSF_RAND_FREQCUTNUM;ii>0;ii--)
        {
            if(shadow_table[(ii-1+chn)%BSF_RAND_FREQCUTNUM] <BSF_RAND_WEIGHT)
            {
                shadow_table[(ii-1+chn)%BSF_RAND_FREQCUTNUM]++;
                break;
            }
        }
    }
    
    chn = get_random_u8();
    if(chn%2)
    {
        for(ii=0;ii<BSF_RAND_FREQCUTNUM;ii++)
        {
            if(shadow_table[(ii+chn)%BSF_RAND_FREQCUTNUM] >BSF_RAND_WEIGHT)
            {
                shadow_table[(ii+chn)%BSF_RAND_FREQCUTNUM] --;
                return;
            }
        }
    }
    else
    {
        for(ii=BSF_RAND_FREQCUTNUM;ii>0;ii--)
        {
            if(shadow_table[(ii-1+chn)%BSF_RAND_FREQCUTNUM] >BSF_RAND_WEIGHT)
            {
                shadow_table[(ii-1+chn)%BSF_RAND_FREQCUTNUM] --;
                return;
            }
        }
    }
    
}

